<?php
/**
 * Zephyr Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://code.google.com/p/zephyr-framework/wiki/License
 *
 * @category   Zephyr
 * @package    Zephyr_Validate
 * @copyright  Copyright (c) 2008 Peo Development Group (http://peo.com.pl)
 * @license    http://code.google.com/p/zephyr-framework/wiki/License     New BSD License
 * @version    $Id: Pesel.php 6 2008-03-20 13:57:48Z w.naruniec $
 */



/**
 * @see Zend_Validate_Abstract
 */
require_once 'Zend/Validate/Abstract.php';


/**
 * Zephyr_Validate_Number_Nip
 * 
 * @category   Zephyr
 * @package    Zephyr_Validate
 * @subpackage Number
 * @copyright  Copyright (c) 2008 Peo Development Group (http://peo.com.pl)
 * @license    http://code.google.com/p/zephyr-framework/wiki/License     New BSD License
 */
class Zephyr_Validate_Number_Pesel extends Zend_Validate_Abstract
{
    const WRONG_LENGTH = 'numberPeselWrongLength';
    const NOT_VALID  = 'numberPeselNotValid';

    /**
     * @var array
     */
    protected $_messageTemplates = array(
        self::WRONG_LENGTH => "PESEL number '%value%' has a wrong length.",
        self::NOT_VALID  => "PESEL number '%value%' is not valid."
    );

    /**
     * @var array
     */
    protected $_weights = array(
        11  => array(9, 7, 3, 1, 9, 7, 3, 1, 9, 7),
    );

    /**
     * Defined by Zend_Validate_Interface
     *
     * Returns true if and only if $value is a valid PESEL number
     *
     * @param  mixed $value
     * @return boolean
     */
    public function isValid($value)
    {
        $valueString = (string) $value;

        $this->_setValue($valueString);

        $this->_strlen = strlen($valueString);

        if (11 != $this->_strlen) {
            $this->_error(self::WRONG_LENGTH);
            return false;
        }

        if (!$this->_isValidChecksum($valueString)) {
            $this->_error(self::NOT_VALID);
            return false;
        }

        return true;
    }

    /**
     * Checks if the provided PESEL number has a valid checksum.
     *
     * @param string $valueString
     * @return boolean
     */
    protected function _isValidChecksum($valueString)
    {
        $checksum = 0;

        for ($i = 0; $i < $this->_strlen-1; $i++) {
            $checksum += $valueString[$i] * $this->_weights[$this->_strlen][$i];
        }

        $mod = $checksum%10;

        $isValid = ($mod == $valueString[$this->_strlen-1]);

        return $isValid;
    }
}
